package com.mrd.gtimpframe.action;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mrd.framework.ui.Jqgrid;
import com.mrd.gtimp.base.entity.User;
import com.mrd.gtimpframe.entity.Dictionary;
import com.mrd.gtimpframe.entity.TGenDeclaPolicyRules;
import com.mrd.gtimpframe.remote.PolicyRulesParam;
import com.mrd.gtimpframe.service.DictionaryService;
import com.mrd.gtimpframe.service.TGenDeclaPolicyRulesService;
import com.mrd.redis.JedisClientClusterImpl;
import com.mrd.util.CombiMethodUtils;
import com.mrd.util.FormBeanUtil;
import com.mrd.util.JsonBinder;
import com.mrd.util.KeyGenerator;
import com.mrd.util.LoginUtil;
import com.mrd.util.R;
import com.mrd.util.ResponseUtils;

/**
 * 根据政策提炼出的，针对报关单某些项目内容符合政策内容时做出提醒的规则
 * 
 * @author han
 * @email qq.com
 * @date 2017-07-25 12:02:20
 */
@Controller
@RequestMapping("policyRules")
public class TGenDeclaPolicyRulesController {
  @Autowired
  private TGenDeclaPolicyRulesService tGenDeclaPolicyRulesService;
  @Autowired
  DictionaryService dictionaryService;
  @Autowired
  JedisClientClusterImpl redisClusterClient;

  @RequestMapping("listPage")
  public String listPage() {
    return "/gtimp/declaPolicy/declaPolicy";
  }

  /**
   * 列表
   */
  @RequestMapping("/list")
  public void list(Jqgrid jqgrid, HttpServletResponse response) throws Exception {
    String result = "";
    Pageable page = jqgrid.getPage();
    int pageNumber = page.getPageNumber();
    int pageSize = page.getPageSize();
    // 分页
    PageHelper.startPage(pageNumber + 1, pageSize);

    // 排序
    Sort.Order order = jqgrid.getOrder();
    if (order != null) {
      String direction = order.getDirection().toString();
      String propertyName = order.getProperty();
      PageHelper.orderBy(propertyName + " " + direction);
    }
    TGenDeclaPolicyRules tGenDeclaPolicyRules =
        FormBeanUtil.getEntityFromJqgrid(jqgrid, TGenDeclaPolicyRules.class);
    List<TGenDeclaPolicyRules> declaPolicyList =
        tGenDeclaPolicyRulesService.queryList(tGenDeclaPolicyRules);
    PageInfo<TGenDeclaPolicyRules> pi = new PageInfo<TGenDeclaPolicyRules>(declaPolicyList);
    Page<Map<String, Object>> pMap = new PageImpl(declaPolicyList, page, pi.getTotal());
    JsonBinder jsonBinder = JsonBinder.buildNormalBinder();
    jsonBinder.setDateFormat("yyyy-MM-dd");
    result = jsonBinder.toJson(pMap);
    ResponseUtils.renderJson(response, result);
  }

  /**
   * 根据政策主键，查询政策下的相关配置信息
   * 
   * @author han
   * @param pruleId 政策主键
   * @return
   */
  @ResponseBody
  @RequestMapping("/manage/policyData")
  public R policyData(String pruleId) {
    R msg = new R();
    try {
      msg = msg.ok();
      PolicyRulesParam.PolicyRules policyRules = tGenDeclaPolicyRulesService.policyData(pruleId);
      List<PolicyRulesParam.Group> groupList = policyRules.getListRule();
      JSONArray contenAry = new JSONArray();
      JSONObject jsonobj = new JSONObject();
      JSONArray ary = new JSONArray();
      if (policyRules != null) {
        jsonobj.put("pruleId", policyRules.getPruleId());
        jsonobj.put("policyCode", policyRules.getPolicyCode());
        jsonobj.put("status", policyRules.getStatus());
        jsonobj.put("eftTimeBegin", policyRules.getEftTimeBegin());
        jsonobj.put("bizSceneId", policyRules.getBizSceneId());
        jsonobj.put("noticeMsg", policyRules.getNoticeMsg());
        jsonobj.put("remark", policyRules.getRemark());
        if (groupList != null && groupList.size() > 0) {
          for (PolicyRulesParam.Group itemGroup : groupList) {
            if (StringUtils.isNotEmpty(itemGroup.getCombiMethod())) {
              ary.add(itemGroup.getCombiMethod());
            }

            // 遍历规则
            JSONArray ruleChild = new JSONArray();
            List<PolicyRulesParam.Rule> ruleList = itemGroup.getList();
            for (PolicyRulesParam.Rule rule : ruleList) {
              if (StringUtils.isNotEmpty(rule.getCombiMethod())) {
                ruleChild.add(rule.getCombiMethod());
              }
              ruleChild.add(rule);
            }

            ary.add(ruleChild);
          }
        }
      }
      contenAry.add(jsonobj);
      jsonobj.put("ruleGroups", ary);
      return msg.put("content", contenAry);
    } catch (Exception ex) {
      return msg.error(ex.getMessage());
    }
  }

  /**
   * 根据场景，查询场景下的多条政策提醒
   * 
   * @see 优化，增加方法级缓存优化，根据场景缓存政策
   * @author han
   * @param bizSence 场景主键
   * @return
   */
  @ResponseBody
  @RequestMapping("/order/policyData")
  @Cacheable(value = "sencePolicy", key = "#bizSence")
  public R orderPolicyData(String bizSence) {
    R msg = new R();
    try {
      msg = msg.ok();
      msg.put("result", true);
      // @todo
      List<Dictionary> listDic = dictionaryService.selectWithDictionaryByCodesIn("rule_eft_item");
      List<Dictionary> bizs = dictionaryService.selectWithDictionaryByCodesIn("biz_sence");
      if (bizSence != null && bizs != null) {
        String bizSenceCode = "";

        for (Dictionary itemDic : bizs) {
          if (itemDic.getDictionaryCode().equals(bizSence)) {
            bizSenceCode = itemDic.getId();
            break;
          }
        }

        if (StringUtils.isNotEmpty(bizSenceCode)) {

          Map<String, Dictionary> dicMap = new HashMap<String, Dictionary>();
          if (listDic != null) {
            for (Dictionary itemDic : listDic) {
              dicMap.put(itemDic.getId(), itemDic);
            }
          }
          List<PolicyRulesParam.PolicyRules> listRule =
              tGenDeclaPolicyRulesService.getSceenPolicyRule(bizSenceCode);
          JSONArray itemRule = new JSONArray();

          if (listRule != null && listRule.size() > 0) {
            for (PolicyRulesParam.PolicyRules rule : listRule) {
              if (StringUtils.isNotEmpty(rule.getStatus()) && rule.getStatus().equals("1")) {
                JSONObject jsObj = orderPolicyChange(rule, dicMap);
                itemRule.add(jsObj);
              }
            }
          }
          return msg.put("data", itemRule);
        } else {
          msg.error("非法场景");
          msg.put("result", false);
          return msg;
        }
      } else {
        msg.error("场景编码不能为空");
        msg.put("result", false);
        return msg;
      }
    } catch (Exception ex) {
      msg.error(ex.getMessage());
      msg.put("result", false);
      return msg;
    }
  }

  /**
   * 保存单个政策提醒相关配置
   * 
   * @author han
   */
  @ResponseBody
  @RequestMapping("/manage/save")
  public R save(HttpServletRequest request) {
    try {
      // 读取参数
      InputStream inputStream;
      StringBuffer sb = new StringBuffer();
      inputStream = request.getInputStream();
      String content;
      BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
      while ((content = in.readLine()) != null) {
        sb.append(content);
      }
      in.close();
      inputStream.close();

      ObjectMapper mapper = new ObjectMapper();
      PolicyRulesParam policyParam = mapper.readValue(sb.toString(), PolicyRulesParam.class);
      PolicyRulesParam.PolicyRules policyRulesStr = null;
      if (policyParam != null) {
        policyRulesStr = policyParam.getData();
        /*** 删除场景下所缓存的政策 *****/
        if (policyRulesStr != null && StringUtils.isNotEmpty(policyRulesStr.getBizSceneId())) {
          List<Dictionary> bizs = dictionaryService.selectWithDictionaryByCodesIn("biz_sence");
          String bizSenceCode = "";

          for (Dictionary itemDic : bizs) {
            if (itemDic.getId().equals(policyRulesStr.getBizSceneId())) {
              bizSenceCode = itemDic.getDictionaryCode();
              redisClusterClient.delete(bizSenceCode);
              break;
            }
          }
        }
        List<Object> itemGroup = policyRulesStr.getRuleGroups();
        for (int i = 0; i < itemGroup.size(); i++) {// 遍历组
          Object item = itemGroup.get(i);
          // 产生组与组之间的关系
          if (item instanceof ArrayList) {// 组
            ArrayList<String> itemRule = (ArrayList<String>) item;
            PolicyRulesParam.Group group = new PolicyRulesParam.Group();
            group.setGroupId(KeyGenerator.generateRadomSequenceNo("group_"));
            for (int j = 0; j < itemRule.size(); j++) {
              Object detailRule = itemRule.get(j);
              if (detailRule instanceof LinkedHashMap) {
                LinkedHashMap<String, String> map = (LinkedHashMap<String, String>) detailRule;
                PolicyRulesParam.Rule rule =
                    FormBeanUtil.getFromLinkMap(map, PolicyRulesParam.Rule.class);
                rule.setRuleId(KeyGenerator.generateRadomSequenceNo("rule_"));
                if (j > 0) {
                  String linkCombiMethod = itemRule.get(j - 1);
                  rule.setCombiMethod(linkCombiMethod);
                }
                group.getList().add(rule);
              }
            }
            if (i > 0) {
              String linkCombiMethod = (String) itemGroup.get(i - 1);
              group.setCombiMethod(linkCombiMethod);
            }
            policyRulesStr.getListRule().add(group);
          }
        }
        User user = (User) LoginUtil.getLoginUser();
        tGenDeclaPolicyRulesService.savePolicyRules(policyRulesStr, user);
      }
      return R.ok();
    } catch (Exception ex) {
      return R.error(ex.getMessage());
    }
  }

  /**
   * 删除
   */
  @ResponseBody
  @RequestMapping("/delete")
  public R delete(@RequestBody String[] ids) {
    try {
      /***** 清空场景的缓存 *********/
      List<String> list = tGenDeclaPolicyRulesService.queryRuleIDsBizScene(ids);
      if (list != null && list.size() > 0) {
        for (String scene : list) {
          redisClusterClient.delete(scene);
        }
      }
      tGenDeclaPolicyRulesService.deleteBatch(ids);
      return R.ok("删除成功");
    } catch (Exception ex) {
      return R.error(ex.getMessage());
    }
  }

  /**
   * 单个订单规则转换方法
   * 
   * @author han
   * @param policyRules
   * @return
   */
  private JSONObject orderPolicyChange(PolicyRulesParam.PolicyRules policyRules,
      Map<String, Dictionary> dicMap) {
    List<PolicyRulesParam.Group> groupList = policyRules.getListRule();
    JSONObject jsonobj = new JSONObject();
    JSONArray ruleIdAry = new JSONArray();
    StringBuffer ary = new StringBuffer();
    if (policyRules != null) {
      if (groupList != null && groupList.size() > 0) {
        for (PolicyRulesParam.Group itemGroup : groupList) {

          if (StringUtils.isNotEmpty(itemGroup.getCombiMethod())) {
            ary.append(CombiMethodUtils.compareCombi(itemGroup.getCombiMethod()));
          }
          ary.append("(");
          // 遍历规则
          StringBuffer ruleChild = new StringBuffer();

          List<PolicyRulesParam.Rule> ruleList = itemGroup.getList();
          for (PolicyRulesParam.Rule rule : ruleList) {
            if (StringUtils.isNotEmpty(rule.getCombiMethod())) {
              ruleChild.append(CombiMethodUtils.compareCombi(rule.getCombiMethod()));
            }
            ruleChild.append(CombiMethodUtils.ruleCombiDic(rule, dicMap));
            if (dicMap.containsKey(rule.getItemId())) {
              ruleIdAry.add(dicMap.get(rule.getItemId()).getDictionaryCode());
            } else {
              ruleIdAry.add(rule.getItemId());
            }

          }
          ary.append(ruleChild);
          ary.append(")");
        }
      }
      jsonobj.put("notice", policyRules.getNoticeMsg());
      jsonobj.put("elements", ruleIdAry);
      jsonobj.put("expression", ary);
    }

    return jsonobj;
  }
}
